/**********************************************************************
 *** *                                                            * ***
 *** *  Copyright (c) 2013 Harmonia Holdings Group LLC            * ***
 *** *                                                            * ***
 *** * Permission is hereby granted to use, modify, copy, and     * ***
 *** * distribute this software and its documentation for any     * ***
 *** * purpose only without profit, provided that the above       * ***
 *** * Copyright Notice appears in all copies and that both the   * ***
 *** * Copyright Notice and this Permission Notice appears in     * ***
 *** * every copy of supporting documentation.  No title to nor   * ***
 *** * ownership of the software is transferred hereby.  The name * ***
 *** * of Harmonia Holdings Group LLC shall not be used in        * ***
 *** * advertising or publicity related to the distribution of    * ***
 *** * the software without specific, written, prior permission.  * ***
 *** * This software is provided as-delivered without expressed   * ***
 *** * or implied warranty.  Harmonia Holdings Group LLC          * ***
 *** * makes no representation about the suitability of this      * ***
 *** * software for any purpose and accepts no responsibility for * ***
 *** * its use.                                                   * ***
 *** *                                                            * ***
 *** ************************************************************** ***
 *** *                                                            * ***
 *** * This program is free software; you can redistribute it     * ***
 *** * and/or modify it under the terms of the GNU General Public * ***
 *** * License as published by the Free Software Foundation;      * ***
 *** * either version 2 of the License, or (at your option) any   * ***
 *** * later version.                                             * ***
 *** *                                                            * ***
 *** * This program is distributed in the hope that it will be    * ***
 *** * useful, but WITHOUT ANY WARRANTY; without even the implied * ***
 *** * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR    * ***
 *** * PURPOSE.  See the GNU General Public License for more      * ***
 *** * details.                                                   * ***
 *** *                                                            * ***
 *** * You should have received a copy of the GNU General Public  * ***
 *** * License along with this program; if not, write to the Free * ***
 *** * Software Foundation, Inc., 51 Franklin Street, Fifth       * ***
 *** * Floor, Boston, MA 02110-1301, USA.                         * ***
 *** *                                                            * ***
 *** * For more information: http://www.gnu.org/licenses/gpl.html * ***
 *** *                                                            * ***
 **********************************************************************/
package org.etexascode.interrep.datamodel;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.etexascode.interrep.datamodel.interfaces.IDistanceable;

/**
 * The lane node model.
 * @author ablatt
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class LaneNode implements Serializable, IDistanceable {

	/** Serial ID. */
	@XmlTransient
	private static final long serialVersionUID = -7691826838934008131L;
	/** The x coordinate. */
	@XmlElement
	protected double x = 0.0;
	/** The y coordinate. */
	@XmlElement
	protected double y = 0.0;
	/** The z coordinate. */
	@XmlElement
	protected double z = 0.0;
	/** The width. */
	@XmlElement
	protected double width = 0.0;

	/** Constructor. */
	public LaneNode() {
	}

	/**
	 * Constructor.
	 * @param x The x coordinate.
	 * @param y The y coordinate.
	 */
	public LaneNode(double x, double y) {
		this.x = x;
		this.y = y;
		z = 0;
		width = 1;
	}

	/**
	 * Constructor.
	 * @param x The x coordinate.
	 * @param y The y coordinate.
	 * @param z The z coordinate.
	 * @param width The width value.
	 */
	public LaneNode(double x, double y, double z, double width) {
		this.x = x;
		this.y = y;
		this.z = z;
		this.width = width;
	}

	/**
	 * Duplicate constructor.
	 * @param node The node to duplicate.
	 */
	public LaneNode(LaneNode node) {
		this.x = node.getX();
		this.y = node.getY();
		this.z = node.getZ();
		this.width = node.getWidth();
	}

	/** String representation of lane node. */
	@Override
	public String toString() {
		StringBuilder ret = new StringBuilder();

		ret.append("x = ");
		ret.append(x);
		ret.append("\n");

		ret.append("y = ");
		ret.append(y);
		ret.append("\n");

		ret.append("z = ");
		ret.append(z);
		ret.append("\n");

		ret.append("width = ");
		ret.append(width);
		ret.append("\n");

		return ret.toString();
	}

	/** Checks if two lane nodes are equal. */
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof LaneNode) {
			LaneNode rhs = (LaneNode) obj;
			return new EqualsBuilder().
					append(x, rhs.x).
					append(y, rhs.y).
					append(z, rhs.z).
					append(width, rhs.width).
					isEquals();
		}
		return false;
	}

	/**
	 * HashCode operation. 
	 * @return A hashcode of the data. 
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(29, 41).
				append(x).
				append(y).
				append(z).
				append(width).
				toHashCode();
	}

	/**
	 * Gets the x coordinate.
	 * @return The x coordinate.
	 */
	public double getX() {
		return x;
	}

	/**
	 * Sets the x coordinate.
	 * @param x The new x coordinate.
	 */
	public void setX(double x) {
		this.x = x;
	}

	/**
	 * Gets the y coordinate.
	 * @return The y coordinate.
	 */
	public double getY() {
		return y;
	}

	/**
	 * Sets the y coordinate.
	 * @param y The new y coordinate.
	 */
	public void setY(double y) {
		this.y = y;
	}

	/**
	 * Gets the z coordinate.
	 * @return The z coordinate.
	 */
	public double getZ() {
		return z;
	}

	/**
	 * Sets the z coordinate.
	 * @param z The new z coordinate.
	 */
	public void setZ(double z) {
		this.z = z;
	}

	/**
	 * Gets the width.
	 * @return The width.
	 */
	public double getWidth() {
		return width;
	}

	/**
	 * Sets the width.
	 * @param width The new width.
	 */
	public void setWidth(double width) {
		this.width = width;
	}
}
